﻿using System;
using System.Collections.Generic;
using System.Text;
using DSStdInstallerCompiler;
using DreamShield.Deployment.ProjectFormatter.Xml;
using DreamShield.Data.Implementations.Luna;
using System.IO;

namespace DreamShieldBindingCompiler
{
    public class SetupCompiler
    {
        #region Messages handler

        protected class SetupCompiler_MessageHanler : CCompilerCallBack
        {
            public virtual SetupCompiler Owner { get; protected set; }

            public SetupCompiler_MessageHanler(SetupCompiler owner)
            {
                Owner = owner;
            }

            #region CCompilerCallBack Membres

            public virtual void HandleError(CCompilerMessageId id, string Message, string Source, object data)
            {
                Owner.HandleError(id, Message, Source, data);
            }

            public virtual bool HandleHint(CCompilerMessageId id, string Message, string Source, object data)
            {
                return Owner.HandleHint(id, Message, Source, data);
            }

            public virtual bool HandleInformation(CCompilerMessageId id, string Message, string Source, object data)
            {
                return Owner.HandleInformation(id, Message, Source, data);
            }

            public virtual void HandleInternalError(CCompilerMessageId id, Exception ex, object data)
            {
                Owner.HandleInternalError(id, ex, data);
            }

            public virtual bool HandleWarning(CCompilerMessageId id, string Message, string Source, object data)
            {
                return Owner.HandleWarning(id, Message, Source, data);
            }

            #endregion
        }

        #endregion

        protected virtual CDeployCompiler StandardCompiler { get; private set; }
        protected virtual DSXmlFormatter XmlCompiler { get; private set; }

        public SetupCompiler()
        {
            StandardCompiler = new CDeployCompiler();
            XmlCompiler = new DSXmlFormatter();

            StandardCompiler.CompilerAddingFileProgress += new DreamShield.Luna.BaseTypes.MTBufferUtils.CopyStreamsCallBackFunction(StandardCompiler_CompilerAddingFileProgress);

        }

        protected virtual void StandardCompiler_CompilerAddingFileProgress(long totalSize, long copiedSize, ref bool cancel)
        {
            
        }

        /// <summary>
        /// Compile a .dscproj file
        /// </summary>
        /// <param name="fileName"></param>
        public virtual bool CompileProject(string fileName)
        {
            CInstallerProject project = new CInstallerProject(
                LunaDatabaseFactory.Factory.LoadFile(fileName, DreamShield.Data.DatabaseOpenFileMode.ReadComplete));

            try
            {
                return StandardCompiler.Compile(project);
            }
            finally
            {
                project.Close();
            }
        }

        /// <summary>
        /// Compile a .xml project file to a .dscproj file
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="generatedDscproj"></param>
        /// <returns></returns>
        public virtual bool CompileXmlProject(string fileName, string generatedDscproj)
        {
            var dscproj_file = XmlCompiler.DeSerialize(fileName);

            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                dscproj_file.CommitAsCopy(fs);
            }

            return true;
        }

        public delegate void CompilerMessageHandler(int MessageId, string MessageIdString, string Message, string Source, object data);

        public event CompilerMessageHandler OnError;
        protected virtual void HandleError(CCompilerMessageId id, string Message, string Source, object data)
        {
            if (OnError != null)
                OnError((int)id, id.ToString(), Message, Source, data);
        }

        public event CompilerMessageHandler OnHint;
        protected virtual bool HandleHint(CCompilerMessageId id, string Message, string Source, object data)
        {
            if (OnHint != null)
                OnHint((int)id, id.ToString(), Message, Source, data);

            return true;
        }

        public event CompilerMessageHandler OnInformation;
        protected virtual bool HandleInformation(CCompilerMessageId id, string Message, string Source, object data)
        {
            if (OnInformation != null)
                OnInformation((int)id, id.ToString(), Message, Source, data);

            return true;
        }

        protected virtual void HandleInternalError(CCompilerMessageId id, Exception ex, object data)
        {
            throw new Exception(ex.Message, ex);
        }

        public event CompilerMessageHandler OnWarning;
        protected virtual bool HandleWarning(CCompilerMessageId id, string Message, string Source, object data)
        {
            if (OnWarning != null)
                OnWarning((int)id, id.ToString(), Message, Source, data);

            return true;
        }
    }
}
